using CollabApp.Domain.Entities.Game;
using CollabApp.Domain.ValueObjects;
using Microsoft.Extensions.Logging;
using System.Text.Json;

namespace CollabApp.Domain.Services
{
    /// <summary>
    /// 画线圈地游戏核心逻辑服务实现
    /// </summary>
    public class LineDrawingGameLogicService : ILineDrawingGameLogicService
    {
        private readonly ILogger<LineDrawingGameLogicService> _logger;

        public LineDrawingGameLogicService(ILogger<LineDrawingGameLogicService> logger)
        {
            _logger = logger;
        }

        /// <summary>
        /// 检查玩家移动是否合法
        /// </summary>
        public Task<MoveResult> ValidatePlayerMove(Guid playerId, Position newPosition, object gameState)
        {
            var result = new MoveResult { IsValid = true, MovementSpeed = 1.0 };

            try
            {
                // 尝试从Json字符串解析游戏状态
                if (gameState is string jsonState)
                {
                    // TODO: 解析JSON状态，目前先简化处理
                    // 基础圆形地图边界检查（默认1000x1000）
                    var centerX = 500f;
                    var centerY = 500f;
                    var mapRadius = 500f;
                    
                    var distanceFromCenter = Math.Sqrt(
                        Math.Pow(newPosition.X - centerX, 2) + 
                        Math.Pow(newPosition.Y - centerY, 2)
                    );

                    if (distanceFromCenter > mapRadius)
                    {
                        result.IsValid = false;
                        result.ErrorMessage = "移动位置超出地图边界";
                        return Task.FromResult(result);
                    }

                    // 基础移动速度设置
                    result.MovementSpeed = 1.0;
                }
                else
                {
                    result.IsValid = false;
                    result.ErrorMessage = "无效的游戏状态格式";
                }

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证玩家移动时发生错误");
                result.IsValid = false;
                result.ErrorMessage = "移动验证失败";
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 检查画线路径是否与其他玩家轨迹碰撞
        /// </summary>
        public Task<CollisionResult> CheckPathCollision(Guid playerId, List<Position> path, object gameState)
        {
            var result = new CollisionResult();

            try
            {
                // TODO: 实现具体的碰撞检测逻辑
                // 这需要检查路径是否与其他玩家的当前画线轨迹相交
                
                // 示例实现框架
                foreach (var segment in GetPathSegments(path))
                {
                    // 检查与其他玩家轨迹的碰撞
                    var collision = CheckSegmentCollision(playerId, segment, gameState);
                    if (collision.HasCollision)
                    {
                        return Task.FromResult(collision);
                    }
                }

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查路径碰撞时发生错误");
                result.HasCollision = true;
                result.CollisionType = "检测错误";
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 计算圈地完成后的领地面积
        /// </summary>
        public Task<TerritoryResult> CalculateTerritory(Guid playerId, List<Position> closedPath, List<Territory> existingTerritories)
        {
            var result = new TerritoryResult();

            try
            {
                // 创建新领地
                var newTerritory = new Territory(closedPath);
                result.NewTerritoryArea = newTerritory.Area;
                result.IsValid = true;

                // 检查是否吞噬了其他玩家的领地
                foreach (var territory in existingTerritories)
                {
                    if (newTerritory.IsCompletelyEngulfed(territory))
                    {
                        result.EngulfedTerritories.Add(territory);
                        result.EngulfedArea += territory.Area;
                    }
                }

                result.TotalTerritoryArea = result.NewTerritoryArea + result.EngulfedArea;

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "计算领地面积时发生错误");
                result.IsValid = false;
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 处理玩家死亡逻辑
        /// </summary>
        public Task<DeathResult> HandlePlayerDeath(Guid playerId, Guid? killerPlayerId, string deathReason)
        {
            var result = new DeathResult
            {
                ShouldRespawn = true,
                RespawnTimeMs = 5000, // 基础复活时间5秒
                RemainingTerritoryArea = 0.2, // 保留20%最大领地面积
                HasPenalty = false
            };

            try
            {
                // 根据死亡原因调整复活时间
                result.RespawnTimeMs = deathReason switch
                {
                    "自撞" => 5000,
                    "被击杀" => 5000,
                    "出界" => 3000,
                    _ => 5000
                };

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "处理玩家死亡时发生错误");
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 计算玩家复活时间
        /// </summary>
        public Task<int> CalculateRespawnTime(Guid playerId, int consecutiveDeaths)
        {
            // 10秒内连续死亡2次以上，复活时间延长至8秒
            if (consecutiveDeaths >= 2)
            {
                return Task.FromResult(8000);
            }

            return Task.FromResult(5000); // 标准复活时间
        }

        /// <summary>
        /// 生成道具
        /// </summary>
        public Task<PowerUp?> GeneratePowerUp(object gameArea, List<PowerUp> existingPowerUps, List<Territory> territoryAreas)
        {
            try
            {
                // 如果已达到最大道具数量，不生成新道具
                if (existingPowerUps.Count >= 3)
                {
                    return Task.FromResult<PowerUp?>(null);
                }

                var random = new Random();
                var powerUpTypes = Enum.GetValues<PowerUpType>();
                var selectedType = powerUpTypes[random.Next(powerUpTypes.Length)];

                // 在无人区域生成道具
                var position = FindSafePowerUpSpawnPosition(territoryAreas);
                if (position == null)
                {
                    return Task.FromResult<PowerUp?>(null);
                }

                var duration = selectedType switch
                {
                    PowerUpType.Lightning => TimeSpan.FromSeconds(8),
                    PowerUpType.Shield => TimeSpan.FromSeconds(12),
                    PowerUpType.Ghost => TimeSpan.FromSeconds(10),
                    PowerUpType.Bomb => TimeSpan.Zero, // 瞬间使用
                    _ => TimeSpan.FromSeconds(10)
                };

                return Task.FromResult<PowerUp?>(new PowerUp(selectedType, position, duration));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "生成道具时发生错误");
                return Task.FromResult<PowerUp?>(null);
            }
        }

        /// <summary>
        /// 应用道具效果
        /// </summary>
        public Task<PowerUpResult> ApplyPowerUpEffect(Guid playerId, PowerUp powerUp, object gameState)
        {
            var result = new PowerUpResult { Applied = true };

            try
            {
                switch (powerUp.Type)
                {
                    case PowerUpType.Lightning:
                        result.Effect = "移动速度提升60%";
                        result.DurationMs = 8000;
                        result.Parameters = new Dictionary<string, object>
                        {
                            ["speedMultiplier"] = 1.6,
                            ["trailWidth"] = 3 // 轨迹更粗
                        };
                        break;

                    case PowerUpType.Shield:
                        result.Effect = "获得护盾保护";
                        result.DurationMs = 12000;
                        result.Parameters = new Dictionary<string, object>
                        {
                            ["invulnerable"] = true,
                            ["speedPenalty"] = 0.9 // 速度稍微降低
                        };
                        break;

                    case PowerUpType.Bomb:
                        result.Effect = "在当前位置创造领地";
                        result.DurationMs = 0;
                        result.Parameters = new Dictionary<string, object>
                        {
                            ["radius"] = 30,
                            ["instantTerritory"] = true
                        };
                        break;

                    case PowerUpType.Ghost:
                        result.Effect = "幽灵状态，可穿越敌方轨迹";
                        result.DurationMs = 10000;
                        result.Parameters = new Dictionary<string, object>
                        {
                            ["canPassThroughTrails"] = true,
                            ["cannotCapture"] = true
                        };
                        break;
                }

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "应用道具效果时发生错误");
                result.Applied = false;
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 检查游戏结束条件
        /// </summary>
        public Task<GameEndResult> CheckGameEndConditions(object gameState)
        {
            var result = new GameEndResult();

            try
            {
                // TODO: 根据实际游戏状态检查结束条件
                // 1. 时间结束
                // 2. 单一玩家占领70%地图
                // 3. 只剩一名存活玩家

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查游戏结束条件时发生错误");
                return Task.FromResult(result);
            }
        }

        /// <summary>
        /// 计算最终排名和积分
        /// </summary>
        public Task<List<PlayerRankResult>> CalculateFinalRanking(List<GamePlayer> players)
        {
            var results = new List<PlayerRankResult>();

            try
            {
                // 按领地面积排序
                var sortedPlayers = players.OrderByDescending(p => p.FinalArea).ToList();

                for (int i = 0; i < sortedPlayers.Count; i++)
                {
                    var player = sortedPlayers[i];
                    var rank = i + 1;
                    
                    // 计算积分变化
                    var scoreChange = CalculateScoreChange(rank, sortedPlayers.Count, (double)player.FinalArea);

                    results.Add(new PlayerRankResult
                    {
                        PlayerId = player.UserId,
                        Rank = rank,
                        TerritoryArea = (double)player.FinalArea,
                        ScoreChange = scoreChange,
                        Stats = new Dictionary<string, object>
                        {
                            ["kills"] = player.KillCount,
                            ["deaths"] = player.DeathCount,
                            ["powerUpsUsed"] = player.PowerUpUsageCount,
                            ["maxTerritory"] = (double)player.MaxTerritoryArea
                        }
                    });
                }

                return Task.FromResult(results);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "计算最终排名时发生错误");
                return Task.FromResult(results);
            }
        }

        /// <summary>
        /// 检查特殊事件触发
        /// </summary>
        public Task<SpecialEvent?> CheckSpecialEventTrigger(string gameMode, double gameProgress)
        {
            if (gameMode != "powerup_carnival" || gameProgress < 0.3)
            {
                return Task.FromResult<SpecialEvent?>(null);
            }

            var random = new Random();
            if (random.NextDouble() > 0.1) // 10%概率
            {
                return Task.FromResult<SpecialEvent?>(null);
            }

            var events = new[]
            {
                new SpecialEvent { Type = "gravity_reverse", Name = "重力反转", DurationMs = 20000 },
                new SpecialEvent { Type = "time_acceleration", Name = "时间加速", DurationMs = 15000 },
                new SpecialEvent { Type = "powerup_rain", Name = "道具雨", DurationMs = 0 },
                new SpecialEvent { Type = "territory_shake", Name = "领地震动", DurationMs = 10000 },
                new SpecialEvent { Type = "transparent_mode", Name = "透明模式", DurationMs = 30000 }
            };

            return Task.FromResult<SpecialEvent?>(events[random.Next(events.Length)]);
        }

        /// <summary>
        /// 应用动态平衡机制
        /// </summary>
        public Task<BalanceResult> ApplyDynamicBalance(List<GamePlayer> players)
        {
            var result = new BalanceResult();

            try
            {
                if (players.Count < 2) return Task.FromResult(result);

                var maxArea = players.Max(p => p.FinalArea);
                var totalMapArea = 1000 * 1000 * Math.PI / 4; // 圆形地图面积
                var maxPercentage = (double)(maxArea / (decimal)totalMapArea * 100);

                // 如果有玩家占领超过40%，应用平衡机制
                if (maxPercentage > 40)
                {
                    result.Applied = true;
                    
                    var leadingPlayer = players.First(p => p.FinalArea == maxArea);
                    var otherPlayers = players.Where(p => p.UserId != leadingPlayer.UserId).ToList();

                    // 领先玩家受到轻微debuff
                    result.Adjustments.Add(new PlayerBalanceAdjustment
                    {
                        PlayerId = leadingPlayer.UserId,
                        AdjustmentType = "speed_debuff",
                        Value = 0.95 // 速度-5%
                    });

                    // 落后玩家获得buff
                    foreach (var player in otherPlayers)
                    {
                        result.Adjustments.Add(new PlayerBalanceAdjustment
                        {
                            PlayerId = player.UserId,
                            AdjustmentType = "powerup_buff",
                            Value = 1.2 // 道具效果+20%
                        });
                    }
                }

                return Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "应用动态平衡时发生错误");
                return Task.FromResult(result);
            }
        }

        // 私有辅助方法

        private List<(Position Start, Position End)> GetPathSegments(List<Position> path)
        {
            var segments = new List<(Position Start, Position End)>();
            for (int i = 0; i < path.Count - 1; i++)
            {
                segments.Add((path[i], path[i + 1]));
            }
            return segments;
        }

        private CollisionResult CheckSegmentCollision(Guid playerId, (Position Start, Position End) segment, object gameState)
        {
            // TODO: 实现具体的线段碰撞检测
            return new CollisionResult();
        }

        private Position? FindSafePowerUpSpawnPosition(List<Territory> territoryAreas)
        {
            var random = new Random();
            var attempts = 0;
            var maxAttempts = 50;

            while (attempts < maxAttempts)
            {
                var x = random.Next(100, 900);
                var y = random.Next(100, 900);
                var position = new Position(x, y);

                // 检查是否在任何领地内
                var isInTerritory = territoryAreas.Any(t => t.Contains(position));
                if (!isInTerritory)
                {
                    return position;
                }

                attempts++;
            }

            return null; // 找不到合适位置
        }

        private int CalculateScoreChange(int rank, int totalPlayers, double territoryArea)
        {
            var baseScore = rank switch
            {
                1 => 100,
                2 => 75,
                3 => 50,
                _ => 25
            };

            // 根据领地面积调整积分
            var areaBonus = (int)(territoryArea / 1000); // 每1000像素面积+1分

            return baseScore + areaBonus;
        }
    }
}